package cn.fxxk.modular.system.controller;

import cn.fxxk.common.Constants;
import cn.fxxk.kernel.model.util.SignUtil;
import cn.fxxk.modular.system.entity.*;
import cn.fxxk.modular.system.model.CrmCallBackArg;
import cn.fxxk.modular.system.model.CrmCallBackResult;
import cn.fxxk.modular.system.service.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mysql.cj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/event/")
public class EventController {
    private static final String SUCCESS = "success";
    private String aesKey = "O1YDM1MTM0ADMwgjN2gDMuAjNxITOuMDM3cjN1UTNyc=";

    @Resource
    private FxxkOpenuseridService fxxkOpenuseridService;
    @Resource
    private FxxkAccesstokenService fxxkAccesstokenService;
    @Resource
    private FxxkUserAccesstokenService fxxkUserAccesstokenService;
    @Resource
    private FxxkUserService fxxkUserService;
    @Resource
    private FxxkAccountService fxxkAccountService;
    @Resource
    private RestTemplate restTemplate;

    @RequestMapping(value = "crmCallback", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public CrmCallBackResult crmCallBack(@RequestBody CrmCallBackArg arg) throws Exception {
        System.out.println("推送进来了");
        Integer retryTimes = arg.getRetryTimes();
        String signature = null;
        if (retryTimes != null) {
            signature = SignUtil.shaEncode(arg.getTimestamp() + arg.getNonce() + arg.getMessageId() + retryTimes + arg.getEnterpriseAccount() + arg.getEncryptedContent() + aesKey);
        } else {
            signature = SignUtil.shaEncode(arg.getTimestamp() + arg.getNonce() + arg.getMessageId() + arg.getEnterpriseAccount() + arg.getEncryptedContent() + aesKey);
        }
        //校验signature
        if (!arg.getSignature().equals(signature)) {
            Long returnTimestamp = System.currentTimeMillis();
            String returnEncryptedResult = SignUtil.encryptAes("sinature is wrong", aesKey);
            String returnNonce = (int) (Math.random() * 100000) + "";
            String returnSignature = SignUtil.shaEncode(returnTimestamp + returnNonce + returnEncryptedResult + aesKey);
            CrmCallBackResult crmCallBackResult = new CrmCallBackResult();
            crmCallBackResult.setTimestamp(returnTimestamp);
            crmCallBackResult.setEncryptedResult(returnEncryptedResult);
            crmCallBackResult.setNonce(returnNonce);
            crmCallBackResult.setSignature(returnSignature);
            log.warn("crmCallBack={}", crmCallBackResult);
            return crmCallBackResult;
        }
        //处理第三方业务逻辑
        String json = SignUtil.decryptAes(arg.getEncryptedContent(), aesKey);
        //....
        //返回结果
        Long returnTimestamp = System.currentTimeMillis();
        String returnEncryptedResult = SignUtil.encryptAes("success", aesKey);
        String returnNonce = (int) (Math.random() * 1000000) + "";
        String returnSignature = SignUtil.shaEncode(returnTimestamp + returnNonce + returnEncryptedResult + aesKey);
        CrmCallBackResult crmCallBackResult = new CrmCallBackResult();
        crmCallBackResult.setTimestamp(returnTimestamp);
        crmCallBackResult.setEncryptedResult(returnEncryptedResult);
        crmCallBackResult.setNonce(returnNonce);
        crmCallBackResult.setSignature(returnSignature);
        log.info("json={},crmCallBack={}", json, crmCallBackResult);
        return crmCallBackResult;
    }

    @RequestMapping(value = "getCodeCallBack", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public void getCode(@RequestParam("code") String code, @RequestParam("state") String state) throws Exception {
        System.out.println("获取code进来了 code=" + code);
        if (!StringUtils.isNullOrEmpty(code)) {
            String url = Constants.GET_OPEN_USER_ID;
            //设置请求头
            HttpHeaders headers = new HttpHeaders();
            //设置content-type
            MediaType type = MediaType.parseMediaType("application/json");
            headers.setContentType(type);
            //设置请求体
            Map<String, Object> params = new HashMap<>();
            params.put("grantType", "authorization_code");
            params.put("appId", Constants.APP_ID);
            params.put("appSecret", Constants.APP_SECRET);
            params.put("redirectUrl", "https://open.fxiaoke.com/xxx");
            params.put("code", code);

            //用HttpEntity封装整个请求报文
            HttpEntity<Map<String, Object>> files = new HttpEntity<>(params, headers);

            //服务端返回的json格式："
            String result = restTemplate.postForObject(url, files, String.class);

            Map<String, Object> mapTypes = JSONObject.parseObject(result);
            if ("success".equals((String) mapTypes.get("errorMessage"))) {
                FxxkUserAccesstoken fxxkAccesstoken = FxxkUserAccesstoken.builder()
                        .id(1)
                        .corpId((String) mapTypes.get("corpId"))
                        .expiresIn((int) mapTypes.get("expiresIn"))
                        .accessToken((String) mapTypes.get("accessToken"))
                        .refreshToken((String) mapTypes.get("refreshToken"))
                        .openUserId((String) mapTypes.get("openUserId"))
                        .createTime(new Date())
                        .build();
                FxxkOpenuserid fxxkOpenuserid = FxxkOpenuserid.builder().id(1).openUserId((String) mapTypes.get("openUserId")).build();
                fxxkOpenuseridService.saveOrUpdate(fxxkOpenuserid);
                fxxkUserAccesstokenService.saveOrUpdate(fxxkAccesstoken);
            } else {
                log.error("accessToken获取失败");
            }
            System.out.println(mapTypes);
        }
    }

    @Transactional
    @RequestMapping(value = "initializationList", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public void list() {
        FxxkAccesstoken fxxkAccesstoken = fxxkAccesstokenService.getById(1);
        FxxkOpenuserid fxxkOpenuserid = fxxkOpenuseridService.getById(1);
        String corpAccessToken = fxxkAccesstoken.getCorpAccessToken();
        String corpId = fxxkAccesstoken.getCorpId();
        String currentOpenUserId = fxxkOpenuserid.getOpenUserId();
        String dataObjectApiName = "AccountObj";
        JSONObject data = new JSONObject();
        JSONObject search_query_info = new JSONObject();
        search_query_info.put("offset", 0);
        search_query_info.put("limit", 10000);
        data.put("search_query_info", search_query_info);
        data.put("dataObjectApiName", dataObjectApiName);
        String url = Constants.QUERY_ACCOUT;
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        //设置content-type
        MediaType type = MediaType.parseMediaType("application/json");
        headers.setContentType(type);
        //设置请求体
        JSONObject params = new JSONObject();
        params.put("corpAccessToken", corpAccessToken);
        params.put("corpId", corpId);
        params.put("currentOpenUserId", currentOpenUserId);
        params.put("data", data);

        //用HttpEntity封装整个请求报文
        HttpEntity<Map<String, Object>> files = new HttpEntity<>(params, headers);

        //服务端返回的json格式："
        String result = restTemplate.postForObject(url, files, String.class);
        if (!StringUtils.isNullOrEmpty(result)) {
            JSONObject jsonResult = JSONObject.parseObject(result);
            JSONObject jsonData = jsonResult.getJSONObject("data");
            if (jsonResult.getInteger("errorCode") == 0) {
                Integer total = jsonData.getInteger("total");
                search_query_info.remove("limit");
                search_query_info.put("limit", total);
                String resultAll = restTemplate.postForObject(url, files, String.class);
                JSONObject jsonResultAll = JSONObject.parseObject(result);
                JSONObject jsonDataAll = jsonResultAll.getJSONObject("data");
                JSONArray jsonDataListAll = jsonDataAll.getJSONArray("dataList");
                System.out.println("jsonDataListAll.size()=" + jsonDataListAll.size());
                for (int i = 0; i < jsonDataListAll.size(); i++) {
                    System.out.println("jsonDataListObj" + jsonDataListAll.getJSONObject(i));
                    JSONObject jsonDataListObj = jsonDataListAll.getJSONObject(i);
                    FxxkUser fxxkUser = FxxkUser.builder()
                            .id(jsonDataListObj.get("_id").toString())
                            .accountNo(jsonDataListObj.getOrDefault("account_no","").toString())
                            .fieldGjs1sC(jsonDataListObj.getLongValue("field_gJS1S__c"))
                            .field28bawC(jsonDataListObj.getOrDefault("field_28baW__c","").toString())
                            .name(jsonDataListObj.getOrDefault("name","").toString())
                            .fieldG2axdC(jsonDataListObj.getOrDefault("field_G2axd__c","").toString())
                            .fieldDs242C(jsonDataListObj.getOrDefault("field_dS242__c","").toString())
                            .tel(jsonDataListObj.getOrDefault("tel","").toString())
                            .fieldP4el1C(jsonDataListObj.getOrDefault("field_P4El1__c","").toString())
                            .field2kxn0C(jsonDataListObj.getOrDefault("field_2kxn0__c","").toString())
                            .fieldP8oihC(jsonDataListObj.getOrDefault("field_p8Oih__c","").toString())
                            .field3wa01C(jsonDataListObj.getOrDefault("field_3wa01__c","").toString())
                            .fieldYmh9xC(jsonDataListObj.getOrDefault("field_yMH9X__c","").toString())
                            .recordType(jsonDataListObj.getOrDefault("record_type","").toString())
                            .field7ax5wC(jsonDataListObj.getOrDefault("field_7Ax5w__c","").toString())
                            .field43v7tC(jsonDataListObj.getOrDefault("field_43v7T__c","").toString())
                            .countryR(jsonDataListObj.getOrDefault("country__r","").toString())
                            .provinceR(jsonDataListObj.getOrDefault("province__r","").toString())
                            .cityR(jsonDataListObj.getOrDefault("city__r","").toString())
                            .districtR(jsonDataListObj.getOrDefault("district__r","").toString())
                            .address(jsonDataListObj.getOrDefault("address","").toString())
                            .createdByR(jsonDataListObj.getJSONObject("created_by__r").getOrDefault("name","").toString())
                            .createTime(jsonDataListObj.getLong("create_time").intValue())
                            .lastFollowedTime(jsonDataListObj.getLong("last_followed_time").intValue())
                            .lastModifiedTime(jsonDataListObj.getLong("last_modified_time").intValue())
                            .build();
                    FxxkAccount fxxkAccount = FxxkAccount.builder()
                            .fxxkUserId(jsonDataListObj.get("_id").toString())
                            .name(jsonDataListObj.getOrDefault("name","").toString())
                            .tel(jsonDataListObj.getOrDefault("tel","").toString())
                            .isDel(0)
                            .createBy("admin")
                            .createTime(jsonDataListObj.getLong("create_time").intValue())
                            .updateBy("admin")
                            .updateTime(jsonDataListObj.getLong("last_modified_time").intValue())
                            .build();
                    fxxkUserService.saveOrUpdate(fxxkUser);
                    fxxkAccountService.saveOrUpdate(fxxkAccount);
                }
            }
        }
    }
}
